import 'dart:convert';

import 'package:archive/archive.dart';
import 'package:event_bus/event_bus.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:todo_app/controllers/definitions/MessageModel.dart';
import 'package:todo_app/utils/mqtt/LocalMqttClient.dart';
import 'package:todo_app/utils/webrtc/RTCMessageModel.dart';

enum RTCMessageResponseType {
  publishedMsg("PUBLISHED_MSG", 0),
  sendMsg("SEND_MSG", 1),
  receivedMsg("RECEIVED_MSG", 2),
  sendMsgError("SEND_MSG_ERROR", 3);

  const RTCMessageResponseType(this.name, this.value);
  final String name;
  final int value;
}

class RTCMessageResponse {
  final RTCMessageResponseType type;
  final RTCMessage payload;

  RTCMessageResponse({ required this.type, required this.payload });
}

class RTCMessageEventBus {
  static EventBus eventBus = EventBus();

  // 发送消息
  static int sendMessage(RTCMessage msg) {
    eventBus.fire(RTCMessageResponse(type: RTCMessageResponseType.sendMsg, payload: msg ));
    var result = LocalMqttClient.publishMessage("/rtc/s", msg);
    return result;
  }

  // 发送消息
  static int sendRtcMessage(RTCMsgType type, int sendUid, String room, dynamic payload) {
    var msg = RTCMessage(
      type: type,
      suid: sendUid,
      room: room,
      payload: payload,
      timestamp: DateTime.now().millisecondsSinceEpoch
    );
    return RTCMessageEventBus.sendMessage(msg);
  }

  static publishedMessage(RTCMessage msg) {
    // TODO: 发送成功后的逻辑
  }

  // 接收消息
  static receivedMessage(MqttPublishMessage recMess) {
    var topic = recMess.variableHeader!.topicName;
    var userId = int.tryParse(topic.replaceAll("/rtc/r/", ""));
    if(userId == null) return;
    final pt = const Utf8Decoder().convert(recMess.payload.message);
    final json = jsonDecode(pt);
    var msg = RTCMessage()..fromJson(json);
    eventBus.fire(RTCMessageResponse(type: RTCMessageResponseType.receivedMsg, payload: msg ));
  }

  ///GZIP 压缩
  static String gzipEncode(String str) {
    //先来转换一下
    List<int> stringBytes = utf8.encode(str);
    //然后使用 gzip 压缩
    List<int>? gzipBytes = GZipEncoder().encode(stringBytes);
    //然后再编码一下进行网络传输
    String compressedString = base64UrlEncode(gzipBytes!);
    return compressedString;
  }

  ///GZIP 解压缩
  static String gzipDencode(String str) {
    //先来解码一下
    List<int> stringBytes = base64Url.decode(str);
    //然后使用 gzip 压缩
    List<int> gzipBytes = GZipDecoder().decodeBytes(stringBytes);
    //然后再编码一下
    String compressedString = utf8.decode(gzipBytes);
    return compressedString;
  }
}

enum MessageCategory {
  group("GROUP"),
  single("SINGLE");

  const MessageCategory(this.name);
  final String name;
}


enum MessageType {
  text("TEXT"),
  image("IMAGE"),
  video("VIDEO");

  const MessageType(this.name);
  final String name;
}

enum MessageCrypto {
  plaintext("plaintext"),
  base64("base64"),
  json("json"),
  hex("hex"),
  sha1("sha1"),
  sha128("sha128"),
  sha256("sha256"),
  md5("md5");

  const MessageCrypto(this.name);
  final String name;
}